
#ifdef ELS_OS_MCU
#include "els.h"
#include "els_libload.h"
#include<stdio.h>
#include<string.h>
char els_buff_tmp[1024];
ELS_API void els_lib_init(els_VmObj *l){
    els_register(l,"import",els_lib_load);
}
ELS_API int els_lib_load(els_VmObj *l){
    int i;
    const char* s = els_getstr(l,1);
    for(i=0; i<sizeof(els_libs)/sizeof(els_libs[0]); i++){
        if(!strcmp(els_libs[i].name,s)){ 
            els_libs[i].func(l);
            return 0;
        }
    }
    printf("Error: Couldn't Load Library: %s\n",s);
    return 1;
}
#endif

#ifdef ELS_OS_LINUX

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<unistd.h>
#include "els.h"
int els_core_inc(els_VmObj *l);
int els_core_eval(els_VmObj *l);

#include<dlfcn.h>

typedef struct LNI_return{
    int type;
    double num;
    char* str;
}LNI_return;
typedef struct LNI_argv{
    int type[16];
    double num[16];
    char* str[16];
}LNI_argv;


int els_FFI_C(els_VmObj *l){
    char incdir[512]="/els/lib/";
    typedef LNI_return (*ELS_C_FFI)(LNI_argv a);
    if(els_isstr(l,1)&&els_isstr(l,2)){
        strcat(incdir,els_getstr(l,1));
        char *libname = (char*)els_getstr(l,1);
        char *funcname = (char*)els_getstr(l,2);
        void* _ptr_dll = dlopen(libname,RTLD_NOW);
        if (!_ptr_dll) _ptr_dll = dlopen(incdir,RTLD_NOW);
        if(!_ptr_dll)   els_error(l,"无法加载C库!");
        ELS_C_FFI c_api;
        LNI_argv argv;
        int i = 1;
        while(i<13){
            argv.type[i] = -els_type(l,i);
            argv.str[i] = (char*)els_getstr(l,i);
            argv.num[i] = els_getnum(l,i);
            i++;
        }
        c_api = (ELS_C_FFI)dlsym(_ptr_dll,funcname);
        if(c_api==NULL) els_error(l,"找不到C函数!");
        LNI_return rt =  c_api(argv); 
        if(rt.type==-ELS_TYPE_NUMBER) {els_pushnum(l,rt.num);}
        if(rt.type==-ELS_TYPE_STRING) {els_pushstr(l,(const char*)rt.str);}
    }
    return 1;
}
extern void els_lib_init(els_VmObj *l){
    #ifdef ELS_LANG_CN
    els_register(l,"库", els_FFI_C);
    els_register(l,"引",els_core_inc);
    els_register(l,"释",els_core_eval);
    #endif
    #ifdef ELS_LANG_EN
    els_register(l,"call", els_FFI_C);
    els_register(l,"import",els_core_inc);
    els_register(l,"eval",els_core_eval);
    #endif
}
int els_core_inc(els_VmObj *l){
    char incdir[512];
    if(els_type(l,1)==ELS_TYPE_NULL) els_error(l,"方法 引 缺少参数");
    sprintf(incdir,"%s%s%s","./",els_getstr(l,1),".els");
    FILE *fi = fopen(incdir,"r");
    if(fi>0){
        fclose(fi);
        els_dofile(l,incdir);
    }else{
        sprintf(incdir,"%s%s%s","/els/inc/",els_getstr(l,1),".els");
        els_dofile(l,incdir);
        els_pushnull(l); 
    }
    return 1;

}
int els_core_eval(els_VmObj *l){
    if(els_type(l,1)==ELS_TYPE_NULL) return 1;
    return els_dostring(l,els_getstr(l,1));
}




#endif

#ifdef ELS_OS_WINDOWS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<windows.h>
#include "els.h"
int els_core_inc(els_VmObj *l);
int els_core_eval(els_VmObj *l);



typedef struct LNI_return{
    int type;
    double num;
    char* str;
}LNI_return;
typedef struct LNI_argv{
    int type[16];
    double num[16];
    char* str[16];
}LNI_argv;

const char* togbk(const char * str){
	int len = MultiByteToWideChar(CP_UTF8,0,str,-1,NULL,0);
	wchar_t *strUnicode = (wchar_t*)malloc(len*sizeof(wchar_t*));
	wmemset(strUnicode,0,len);
	MultiByteToWideChar(CP_UTF8,0,str,-1,strUnicode,len);
	len = WideCharToMultiByte(CP_ACP,0,strUnicode,-1,NULL,0,NULL,NULL);
	char* strGbk = (char*)malloc(len*sizeof(char*));
	memset(strGbk,0,len);
	WideCharToMultiByte(CP_ACP,0,strUnicode,-1,strGbk,len,NULL,NULL);
	free(strUnicode);
	strUnicode=NULL;
	return strGbk;
}
const char* toutf8(const char* str){
	int len = MultiByteToWideChar(CP_ACP,0,str,-1,NULL,0);
	wchar_t* strUnicode = (wchar_t*)malloc(len*sizeof(wchar_t*));
	wmemset(strUnicode,0,len);
	MultiByteToWideChar(CP_ACP,0,str,-1,strUnicode,len);
	len = WideCharToMultiByte(CP_UTF8,0,strUnicode,-1,NULL,0,NULL,NULL);
	char* strutf8 = (char*)malloc(len*sizeof(char*));
    memset(strutf8,0,len);
	WideCharToMultiByte(CP_UTF8,0,strUnicode,-1,strutf8,len,NULL,NULL);
	free(strUnicode);
	strUnicode=NULL;
	return strutf8;
}


int els_FFI_C(els_VmObj *l){
    char incdir[512];/*"C:/els/lib"*/
    typedef LNI_return (*ELS_C_FFI)(LNI_argv a);
    if(els_isstr(l,1)&&els_isstr(l,2)){
        if(getenv("LOSU")==NULL) els_error(l,"找不到环境变量 LOSU");
        sprintf(incdir,"%s/lib/%s",getenv("LOSU"),togbk(els_getstr(l,1)));
        char *libname = els_getstr(l,1);
        char *funcname = els_getstr(l,2);
        HMODULE  _ptr_dll =  LoadLibrary(togbk(libname));
        if(!_ptr_dll) _ptr_dll = LoadLibrary(incdir);
        if(!_ptr_dll) els_error(l,"无法加载C库");
        ELS_C_FFI c_api;
        LNI_argv argv;
        int i = 0;
        while(i<13){
            ++i;
            argv.type[i] = -els_type(l,i);
            argv.str[i] = els_getstr(l,i);
            argv.num[i] = els_getnum(l,i);
        }
        c_api = (ELS_C_FFI)GetProcAddress(_ptr_dll,funcname);
        if(c_api==NULL) els_error(l,"找不到C函数!");
        LNI_return rt =  c_api(argv); 
        if(rt.type==-ELS_TYPE_NUMBER) els_pushnum(l,rt.num);
        if(rt.type==-ELS_TYPE_STRING) els_pushstr(l,rt.str);
    }
    return 1;
}
extern void els_lib_init(els_VmObj *l){
    #ifdef ELS_LANG_CN
    els_register(l,"库", els_FFI_C);
    els_register(l,"引",els_core_inc);
    els_register(l,"释",els_core_eval);
    #endif
    #ifdef ELS_LANG_EN
    els_register(l,"call", els_FFI_C);
    els_register(l,"import",els_core_inc);
    els_register(l,"eval",els_core_eval);
    #endif
}
int els_core_inc(els_VmObj *l){
    if(getenv("LOSU")==NULL) els_error(l,"找不到环境变量 LOSU");
    char incdir[512];
    if(els_type(l,1)==ELS_TYPE_NULL) els_error(l,"方法 引 缺少参数");
    sprintf(incdir,"./%s.els",togbk(els_getstr(l,1)));
    FILE *fi = fopen(incdir,"r");
    if(fi>0){
        fclose(fi);
        els_dofile(l,togbk(incdir));
    }else{
        
        sprintf(incdir,"%s/inc/%s.els",getenv("LOSU"),togbk(els_getstr(l,1)));
        FILE *fi = fopen(incdir,"r");
        if(!(fi>0)){ 
            fclose(fi);
            printf("%s\n",togbk("无法加载指定文件"));
        }
        els_dofile(l,incdir);
        els_pushnull(l);
    }
    return 1;

}
int els_core_eval(els_VmObj *l){
    if(els_type(l,1)==ELS_TYPE_NULL) return 1;
    return els_dostring(l,els_getstr(l,1));
}



#endif